package fr.pud.client.view.mapstation;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import org.openstreetmap.gui.jmapviewer.Coordinate;

import fr.pud.client.controller.bubble.ShowClientInformation;
import fr.pud.client.controller.bubble.ShowVehicleInformation;
import fr.pud.client.i18n.LanguagesConstants;
import fr.pud.client.model.PUDStation;
import fr.pud.client.view.JMapViewerExtended;

/**
 * This class designed a bubble where all the information of an address could be
 * found
 * @author Simon Devineau, Pierre Reliquet
 */
public class Bubble {
    /**
     * The single instance of the bubble
     */
    private static Bubble singleton = null;
    /**
     * The panel where all the component will be inserted
     */
    private static JPanel bubble;

    /**
     * @return the JPanel which represents the bubble
     */
    public static JPanel getBubble(int typeOfBubble) {
        init(typeOfBubble);
        return bubble;
    }

    /**
     * This method creates the JPanel which represents the bubble
     * @param c
     *            , the coordinates of the address where the bubble will be
     *            painted
     * @return the JPanel of the bubble
     */
    public static JPanel getBubble(PUDStation station, int typeOfBubble) {
        init(typeOfBubble);
        setLatitude(station.getAddress().getCoordinate().getLat());
        setLongitude(station.getAddress().getCoordinate().getLon());
        getLabelLatitude().setText(LAT + getLatitude());
        getLabelLongitude().setText(LON + getLongitude());
        getTextAddress().setText(station.getAddress().getAddressName());
        showVehicleInfo = new ShowVehicleInformation(station);
        getVehicle().setAction(showVehicleInfo);
        showClientInfo = new ShowClientInformation(station);
        getPUD().setAction(showClientInfo);
        return bubble;
    }

    /**
     * @return the button close of the bubble
     */
    public static JButton getButtonClose() {
        return buttonClose;
    }

    /**
     * @return the coordinate of the bubble
     */
    public static Coordinate getCoordinate() {
        return new Coordinate(latitude, longitude);
    }

    /**
     * @return the height of the bubble
     */
    public static int getHeight() {
        return BubbleBackground.getHeight()
                + BubbleSubBackground
                        .getHeight(BubbleSubBackground.CENTER_SUB_BUBBLE);
    }

    /**
     * @return the JLabel which contains the latitude
     */
    private static JLabel getLabelLatitude() {
        return labelLatitude;
    }

    /**
     * @return the JLabel which contains the longitude
     */
    private static JLabel getLabelLongitude() {
        return labelLongitude;
    }

    /**
     * @return the latitude of the address
     */
    public static double getLatitude() {
        return latitude;
    }

    /**
     * @return the longitude of the address
     */
    public static double getLongitude() {
        return longitude;
    }

    public static JButton getPUD() {
        return pud;
    }

    /**
     * @return the JTexteArea of the bubble
     */
    public static JTextArea getTextAddress() {
        return textAddress;
    }

    /**
     * @return the JTextField of the bubble
     */
    public static JTextField getTextStation() {
        return textStation;
    }

    public static JButton getVehicle() {
        return vehicle;
    }

    /**
     * @return the width of the bubble
     */
    public static int getWidth() {
        return BubbleBackground.getWidth();
    }

    /**
     * If the instance of the bubble is null this method create a new instance
     * of the bubble
     */
    private static void init(int typeOfBubble) {
        if (singleton == null) {
            bubbleType = typeOfBubble;
            singleton = new Bubble(typeOfBubble);
        }
        else {
            if (bubbleType != typeOfBubble) {
                bubble.remove(subBubble);
                bubbleType = typeOfBubble;
                subBubble = new JLabel(
                        BubbleSubBackground.getImageIcon(typeOfBubble));
                preparesubBubble(typeOfBubble);
            }
        }
    }

    /**
     * Identify the well sub bubble to use and add it to the bubble
     * @param typeOfBubble
     *            , an int which represents a sub bubble
     */
    private static void preparesubBubble(int typeOfBubble) {
        if (typeOfBubble == BubbleSubBackground.TOP_RIGHT_SUB_BUBBLE
                || typeOfBubble == BubbleSubBackground.TOP_LEFT_SUB_BUBBLE
                || typeOfBubble == BubbleSubBackground.CENTER_TOP_SUB_BUBBLE) {
            bubble.add(subBubble, BorderLayout.NORTH);
        }
        else {
            bubble.add(subBubble, BorderLayout.SOUTH);
        }
    }

    /**
     * Modify the value of the address latitude
     * @param latitude
     *            , the new value of the latitude
     */
    private static void setLatitude(double latitude) {
        Bubble.latitude = latitude;
    }

    /**
     * Modify the value of the address longitude
     * @param longitude
     *            , the new value of the longitude
     */
    private static void setLongitude(double longitude) {
        Bubble.longitude = longitude;
    }

    /**
     * The singleton background of the bubble
     */
    private JLabel                        bubbleBackground;
    /**
     * The singleton of the south part of the bubble
     */
    private static JLabel                 subBubble;
    /**
     * A string constant = "Lat : "
     */
    private static final String           LAT         = "Lat : ";
    /**
     * A label where the latitude of the address will be written
     */
    private static JLabel                 labelLatitude;
    /**
     * The value of the latitude
     */
    private static double                 latitude;
    /**
     * A string constant = "Lon : "
     */
    private static final String           LON         = "& Lon : ";
    /**
     * A label where the longitude of the address will be written
     */
    private static JLabel                 labelLongitude;
    /**
     * The value of the longitude
     */
    private static double                 longitude;
    /**
     * A button to display all the information of the vehicle
     */
    private static JButton                vehicle;
    /**
     * A button to display the information of the shop
     */
    private static JButton                pud;
    /**
     * An action for the button vehicle
     */
    private static ShowVehicleInformation showVehicleInfo;
    /**
     * An action to show the client information
     */
    private static ShowClientInformation  showClientInfo;
    /**
     * A button which closes the bubble
     */
    private static JButton                buttonClose = new JButton(
                                                              (String) LanguagesConstants.LANGUAGE
                                                                      .getObject(LanguagesConstants.CLOSE));
    /**
     * A JTextArea where the user will input the address of the station
     */
    private static JTextArea              textAddress = new JTextArea("", 3, 25);
    /**
     * A JTextField where the user will input the name of the station
     */
    private static JTextField             textStation = new JTextField(15);
    /**
     * Int which defined the type of the bubble (bubble with a left,tight ...
     * sub bubble)
     */
    private static int                    bubbleType;

    /**
     * Create a new instance of the bubble
     */
    private Bubble(int typeOfBubble) {
        /*
         * The panel
         */
        bubble = new JPanel();
        bubble.setLayout(new BorderLayout());
        bubble.setOpaque(false);
        /*
         * The label
         */
        this.bubbleBackground = new JLabel(BubbleBackground.getImageIcon());
        this.bubbleBackground.setLayout(new BoxLayout(this.bubbleBackground,
                BoxLayout.PAGE_AXIS));
        subBubble = new JLabel(BubbleSubBackground.getImageIcon(typeOfBubble));
        subBubble.setVisible(true);
        this.prepareBubble(typeOfBubble);
    }

    /**
     * prepare the body of the bubble
     * @return the JPanel of the bubble body
     */
    private JPanel prepareBody() {
        JLabel labelAddress = new JLabel(
                LanguagesConstants.LANGUAGE
                        .getObject(LanguagesConstants.ADDRESS) + ": ");
        textAddress.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        JScrollPane scrollTextAdress = new JScrollPane(textAddress);
        JPanel body = new JPanel(new FlowLayout(FlowLayout.LEFT));
        body.add(labelAddress);
        body.add(scrollTextAdress);
        body.setOpaque(false);
        return body;
    }

    /**
     * A Method wich prepare the layout of the bubble
     */
    private void prepareBubble(int typeOfBubble) {
        /*
         * The header
         */
        JPanel header = this.prepareHeader();
        this.bubbleBackground.add(header);
        /*
         * The body
         */
        JPanel body = this.prepareBody();
        this.bubbleBackground.add(body);
        /*
         * The footer
         */
        JPanel footer = this.prepareFooter();
        this.bubbleBackground.add(footer);
        /*
         * The subfooter
         */
        this.bubbleBackground.setVisible(true);
        this.bubbleBackground.setOpaque(false);
        /*
         * Adding the two parts of the bubbles in the panel
         */
        bubble.add(this.bubbleBackground, BorderLayout.CENTER);
        preparesubBubble(typeOfBubble);
        JMapViewerExtended.getJMapViewer().add(bubble);
    }

    /**
     * Prepare the bubble footer
     * @return the Jpanel of the bubble footer
     */
    private JPanel prepareFooter() {
        vehicle = new JButton();
        pud = new JButton("Pick up");
        JPanel footer = new JPanel(new FlowLayout());
        footer.add(vehicle);
        footer.add(pud);
        footer.setOpaque(false);
        buttonClose.setBackground(Color.WHITE);
        buttonClose.setToolTipText((String) LanguagesConstants.LANGUAGE
                .getObject(LanguagesConstants.CLOSE_DESCRIPTION));
        footer.add(buttonClose);
        footer.setOpaque(false);
        return footer;
    }

    /**
     * prepare the head of the bubble
     * @return the JPanel of the bubble head
     */
    private JPanel prepareHeader() {
        labelLatitude = new JLabel("Lat : ");
        labelLongitude = new JLabel(" | Lon : ");
        JPanel header = new JPanel(new FlowLayout());
        header.add(labelLatitude);
        header.add(labelLongitude);
        header.setOpaque(false);
        return header;
    }
}
